﻿Public Class clsStoret
    Inherits clsWebProvider

    Private WithEvents StoretRes As New StoretResult.StoretResultService
    Private WithEvents StoretSta As New StoretStation.StationService
    Private WithEvents StoretPrj As New StoretProject.ProjectCatalogService
    Private WithEvents StoretCat As New StoretStationCatalog.StationCatalogService

    Public Overrides ReadOnly Property Description As String
        Get
            Return "The USEPA STORET/WQX (U.S. Environmental Protection Agency, Storage & Retrieval/Water Quality Exchange) web service provides native access to water quality data collected by the EPA and numerous other agencies. For more information see http://www.epa.gov/storet."
        End Get
    End Property

    Public Overrides ReadOnly Property URL As String
        Get
            Return "http://www.epa.gov/storet"
        End Get
    End Property

    Public Overrides Function GetStations(Optional NameFilter As String = "") As Boolean
        Try
            LastException = Nothing
            Cancelled = False
            dictStations.Clear()
            dictAgencies.Clear()
            dictParameters.Clear()

            Dim ds As New DataSet

            With AreaOfInterest
                Dim xml As String = ""
                xml = StoretSta.getStationsForMap(.Top, .Bottom, .Left, .Right)
                'xml = CType(StoretSta.getStationsForMap(.Top, .Bottom, .Left, .Right), Xml.XmlNode).OuterXml
                ds.ReadXml(New IO.StringReader(xml))
            End With

            'must crawl through relations to gather up all data in dataset, converting hierachical dataset into flat data file for import

            If ds.Tables.Count > 0 Then
                For Each drOrganization As DataRow In ds.Tables("Organization").Rows
                    Dim drOrganizationDescription As DataRow = drOrganization.GetChildRows("Organization_OrganizationDescription")(0) '1 to 1 relationship
                    Dim AgencyID As String = TestNull(drOrganizationDescription.Item("OrganizationIdentifier"), "")
                    Dim AgencyName As String = TestNull(drOrganizationDescription.Item("OrganizationFormalName"), "")
                    For Each drMonitoringLocation As DataRow In drOrganization.GetChildRows("Organization_MonitoringLocation")
                        Dim SiteID As String = ""
                        Dim StaName As String = ""
                        Dim StaType As String = ""
                        Dim MonLocID As String = ""
                        Dim Latitude As String = ""
                        Dim Longitude As String = ""
                        Dim HUC As String = ""
                        For Each drMonitoringLocationIdentity As DataRow In drMonitoringLocation.GetChildRows("MonitoringLocation_MonitoringLocationIdentity")
                            SiteID = TestNull(drMonitoringLocationIdentity.Item("MonitoringLocationIdentifier"), "")
                            StaName = TestNull(drMonitoringLocationIdentity.Item("MonitoringLocationName"), "")
                            StaType = TestNull(drMonitoringLocationIdentity.Item("MonitoringLocationTypeName"), "")
                            MonLocID = TestNull(drMonitoringLocationIdentity.Item("MonitoringLocation_ID"), "")
                        Next
                        For Each drMonitoringLocationGeospatial As DataRow In drMonitoringLocation.GetChildRows("MonitoringLocation_MonitoringLocationGeospatial")
                            Latitude = TestNull(drMonitoringLocationGeospatial.Item("LatitudeMeasure"), "")
                            Longitude = TestNull(drMonitoringLocationGeospatial.Item("LongitudeMeasure"), "")
                        Next
                        Dim StationID As String = AgencyID & ":" & SiteID
                        If NameFilter = "" OrElse StaName.ToUpper.Contains(NameFilter.ToUpper) Then
                            If Not dictStations.ContainsKey(SiteID.Trim) Then
                                dictStations.Add(StationID, New clsStation(SiteID, StationID, StaName, StaType, AgencyID, AgencyName, Latitude, Longitude, "", HUC))
                            End If
                            If Not dictAgencies.ContainsKey(AgencyID) Then dictAgencies.Add(AgencyID, New clsAgency(AgencyID, AgencyName))
                        End If
                    Next
                Next
            End If

            'If Not GetSeries() Then Return False

            Return True
        Catch ex As Exception
            LastException = ex
            Return False
        End Try
    End Function

    Public Overrides Function GetParameters(Optional NameFilter As String = "") As Boolean
        Try
            LastException = Nothing
            Cancelled = False

            Dim ds As New DataSet

            Dim CharType() As String = {"Physical", "Microbiological", "Nutrient", "Metal", "Other"}

            Dim cnt As Integer = 0
            For s As Integer = 0 To SelectedStations.Count - 1
                Dim sta As clsStation = dictStations(SelectedStations(s))
                'For Each sta In dictStations.Values
                For Each ct As String In CharType
                    Dim StaID As String = sta.StationID.Split(":")(1)
                    Dim OrgID As String = sta.StationID.Split(":")(0)
                    Dim xml As String = ""
                    xml = StoretCat.getStationCharacteristicSummary(ct, StaID, OrgID)
                    'xml = CType(StoretCat.getStationCharacteristicSummary(ct, StaID, OrgID)(0), Xml.XmlNode).OuterXml
                    ds.ReadXml(New IO.StringReader(xml)) 'note: dataset keeps accumulating results
                Next
                cnt += 1
                If Not SetProgress(cnt, dictStations.Count - 1, "Getting summary info...") Then Return False
            Next

            dictParameters.Clear()

            If ds.Tables.Count > 0 Then
                For Each drOrganization As DataRow In ds.Tables("Organization").Rows
                    For Each drStation As DataRow In drOrganization.GetChildRows("Organization_Station")
                        Dim key As String = TestNull(drOrganization("organizationId"), "") & ":" & TestNull(drStation("stationId"), "")
                        With dictStations(key)
                            .HUC = TestNull(drStation("hydrologicUnitCode"), "")
                            .AgencyCode = TestNull(drOrganization("organizationId"), "")
                            .AgencyName = TestNull(drOrganization("organizationName"), "")
                        End With
                        For Each drCharTypeResult In drStation.GetChildRows("Station_CharTypeResults")
                            For Each drCharacteristicResult In drCharTypeResult.GetChildRows("CharTypeResults_CharacteristicResults")
                                Dim PCode As String = TestNull(drCharacteristicResult("Characteristic"), "")
                                Dim dtStart As Date = TestNull(drStation("ActivityStartDate"), Date.MinValue)
                                Dim dtStop As Date = TestNull(drStation("ActivityStopDate"), Date.MinValue)
                                If StartDate < dtStop Or EndDate > dtStart Then
                                    If Not dictParameters.ContainsKey(PCode) Then
                                        Dim Parm As New clsParameter(TestNull(drStation("stationID"), ""), PCode, PCode, PCode, "", 0, dtStart, dtStop, PCode)
                                        dictParameters.Add(PCode, Parm)
                                    End If
                                    With dictParameters(PCode)
                                        .Count += TestNull(drCharacteristicResult("ResultCount"), 0)
                                    End With
                                End If
                            Next
                        Next
                    Next
                Next
            End If

            Return True
        Catch ex As Exception
            LastException = ex
            Return False
        End Try
    End Function

    Public Overrides Function GetResults() As Boolean
        Try
            LastException = Nothing
            Cancelled = False
            lstData.Clear()

            Dim ResultType As String = "regular" ' possible values are "regular", "biological" or "habitat"

            Dim AllParmsSelected As Boolean = (dictParameters.Count = SelectedParameters.Count)

            Dim ds As New DataSet
            'note: dictParameters was previously filled with just Characteristic Names, however when you download the data, need to distinguish data with different sample fractions and units
            dictParameters.Clear()

            For s As Integer = 0 To SelectedStations.Count - 1
                Dim sta As clsStation = dictStations(SelectedStations(s))
                Dim pmax As Integer = IIf(AllParmsSelected, 0, SelectedParameters.Count - 1)

                For p As Integer = 0 To pmax
                    Dim paramName As String = ""
                    If Not AllParmsSelected Then paramName = SelectedParameters(p)
                    If Not SetProgress(s * (pmax + 1), (SelectedStations.Count) * (pmax + 1), String.Format("Getting results for {0}{1}; {2} values so far...", SelectedStations(s), IIf(paramName <> "", " (" & paramName & ")", ""), lstData.Count)) Then Return False

                    With sta
                        StoretRes.Timeout = Timeout * 1000
                        Dim xml As String = StoretRes.getResults(.AgencyCode, .SiteID, "", StartDate.ToString("MM/dd/yyyy"), EndDate.ToString("MM/dd/yyyy"), "", "", "", "", "", paramName, ResultType)
                        ds.ReadXml(New IO.StringReader(xml)) 'note: dataset keeps accumulating results
                    End With
                Next
            Next

            If ds.Tables.Count = 0 Then Return False

            'the dataset has accumulated records, so extract them all now
            Dim StationID As String = ""
            Dim StationName As String = ""
            Dim AgencyCode As String = ""
            Dim Network As String = ""
            Dim PCode As String = ""
            Dim Units As String = ""
            Dim CCode As String = ""
            Dim RCode As String = ""
            Dim DateTime As Date = Date.MinValue
            Dim Result As Double = Double.MaxValue

            For Each drOrganization As DataRow In ds.Tables("Organization").Rows
                For Each drOrganizationDescription As DataRow In drOrganization.GetChildRows("Organization_OrganizationDescription")
                    AgencyCode = CStr(GetValue(drOrganizationDescription, "OrganizationIdentifier", "")).Trim
                Next
                For Each drActivity As DataRow In drOrganization.GetChildRows("Organization_Activity")
                    For Each drMonitoringLocation As DataRow In drActivity.GetChildRows("Activity_MonitoringLocation")
                        StationID = AgencyCode & ":" & GetValue(drMonitoringLocation, "MonitoringLocationIdentifier", "")
                    Next
                    For Each drActivityDescription As DataRow In drActivity.GetChildRows("Activity_ActivityDescription")
                        If Not IsDBNull(drActivityDescription("ActivityStartDate")) Then
                            DateTime = CDate(drActivityDescription("ActivityStartDate") & " " & GetValue(drActivityDescription, "ActivityStartTime", ""))
                        End If
                    Next
                    For Each drResult As DataRow In drActivity.GetChildRows("Activity_Result")
                        For Each drResultDescription As DataRow In drResult.GetChildRows("Result_ResultDescription")
                            RCode = GetValue(drResultDescription, "ResultDetectionConditionText", "")
                            If RCode.Trim.ToUpper.Contains("NON-DETECT") Then
                                RCode = "<"
                            ElseIf RCode.Trim.ToUpper.Contains(">") Then
                                RCode = ">"
                            ElseIf RCode.Trim = "" Then
                            ElseIf RCode.Trim.ToUpper = "*TEXT" Then
                            Else
                                Debug.Fail("check this out: " & RCode)
                            End If

                            Dim CharName As String = CStr(GetValue(drResultDescription, "CharacteristicName", "")).Trim
                            Dim SampFrac As String = CStr(GetValue(drResultDescription, "ResultSampleFractionText", "")).Trim
                            Debug.Assert(GetValue(drResultDescription, "DataQuality", "") = "")

                            For Each drMeasure As DataRow In drResultDescription.GetChildRows("ResultDescription_ResultMeasure")
                                Result = GetValue(drMeasure, "ResultMeasureValue", Double.MaxValue)
                                Units = CStr(GetValue(drMeasure, "MeasureUnitCode", "")).Trim
                                If Units = "ppb" Then Units = "ug/l" 'to prevent there from being duplicate entries when mapping
                                PCode = CharName & IIf(SampFrac = "", "", "; " & SampFrac) & IIf(Units = "", "", "; " & Units)
                                If Not dictParameters.ContainsKey(PCode) Then dictParameters.Add(PCode, New clsParameter("", PCode, PCode, CharName, Units, 0, StartDate, EndDate))
                                If StationID <> "" AndAlso DateTime <> Date.MinValue AndAlso PCode <> "" AndAlso (RCode <> "" OrElse Result <> Double.MaxValue) Then
                                    lstData.Add(New WRDB.Project.clsDataRecord(StationID, DateTime, PCode, Result, CCode, RCode, , , AgencyCode))
                                End If
                            Next
                        Next
                    Next
                Next
            Next
            Return True
        Catch ex As Exception
            LastException = ex
            Cancelled = True
            Return False
        End Try
    End Function

    Public Overrides Function GetResultCount(QuickCount As Boolean) As Boolean
        Try
            If SelectedParameters.Count = 0 Then Return False

            'for each agency, make comma-separated list of selected stations and get total count
            LastException = Nothing
            Cancelled = False
            DataCount = 0

            If QuickCount Then 'get result count from previous station catalog query
                For Each PCode As String In SelectedParameters
                    With dictParameters(PCode)
                        DataCount += .Count
                    End With
                Next
            Else 'requery to get more precise result count -- (not really more precise at all!)
                Dim ResultType As String = "regular" ' possible values are "regular", "biological" or "habitat"
                For Each Agency As clsAgency In dictAgencies.Values
                    Dim AgencyCode As String = Agency.AgencyCode
                    Dim SiteID As String = ""
                    For Each sta As clsStation In dictStations.Values
                        If SelectedStations.Contains(sta.StationID) Then
                            With sta
                                If .AgencyCode = AgencyCode Then
                                    SiteID &= IIf(SiteID = "", "", ",") & .SiteID
                                End If
                            End With
                        End If
                    Next
                    If SiteID <> "" Then
                        Dim AllParmsSelected As Boolean = (dictParameters.Count = SelectedParameters.Count)
                        Dim pmax As Integer = IIf(AllParmsSelected, 0, SelectedParameters.Count - 1)
                        For p As Integer = 0 To pmax
                            Dim paramType As String = IIf(AllParmsSelected, "", SelectedParameters(p))
                            If Not SetProgress(p, pmax, "Getting result count...") Then Return False
                            DataCount += StoretRes.getResultCount(AgencyCode, SiteID, "", StartDate.ToString("MM/dd/yyyy"), EndDate.ToString("MM/dd/yyyy"), "", "", "", "", paramType, "", ResultType)
                        Next
                    End If
                Next
            End If
            Return True
        Catch ex As Exception
            LastException = ex
            Return False
        End Try
    End Function

    Private Sub SaveXML(ByVal Xml As Xml.XmlNode, ByVal FileName As String)
        Dim dir As String = IO.Path.GetDirectoryName(FileName)
        If Not My.Computer.FileSystem.DirectoryExists(dir) Then My.Computer.FileSystem.CreateDirectory(dir)
        Dim sw As New IO.StreamWriter(FileName, False)
        sw.Write(Xml.OuterXml)
        sw.Close()
    End Sub

End Class
